﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using lopet.Repositories;

namespace lopet.data
{
    public class GaussianRandom
    {
        public double Mean { get; set; }
        public double StdDev { get; set; }

        private double? reserveStdNormal = null;

        private RandomNumberRepository _randomNumbersRepository;

        public GaussianRandom()
        {
            _randomNumbersRepository = RandomNumberRepository.Instance;
        }

        public double NextDouble()
        {
            lock (this)
            {
                if (reserveStdNormal != null)
                {
                    var temp = reserveStdNormal.Value;
                    reserveStdNormal = null;
                    return (Mean + StdDev * temp);
                }    
            }

            var u1 = _randomNumbersRepository.NextDouble;
            var u2 = _randomNumbersRepository.NextDouble;
            
            double randStdNormal1 = Math.Sqrt(-2.0 * Math.Log(u1)) *
                         Math.Sin(2.0 * Math.PI * u2); //random normal(0,1)
                        
            reserveStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) *
                         Math.Cos(2.0 * Math.PI * u2); //random normal(0,1)
            
            return (Mean + StdDev * randStdNormal1);
        }
    }
}
